#include "CommandFrameBuilder.h"
#include <QDebug>



CommandFrameBuilder::CommandFrameBuilder() {
    qDebug() << "CommandFrameBuilder initialized";
}

CommandFrameBuilder::~CommandFrameBuilder() {
    qDebug() << "CommandFrameBuilder destroyed";
}

/**
 * @brief 获取帧总长
 * @return  帧总长
 */
uint32_t CommandFrameBuilder::getFrameTotalLength()
{
    return FRAME_TOTAL_LENGTH;
}

/**
 * @brief 构建通用命令帧
 * 构建包含指定命令码和参数的标准命令帧
 * @param commandCode 命令代码
 * @param parameters 参数数据（最多8字节）
 * @return 完整的12字节命令帧
 */
QByteArray CommandFrameBuilder::buildCommandFrame(uint8_t commandCode, const QByteArray& parameters) {
    // 详细的调试日志，包含命令码和参数数量
    qDebug() << QString("[CommandFrameBuilder] Building command frame: code=0x%1 (%2), params=%3 bytes").arg(commandCode, 2, 16, QChar('0')).arg(getCommandDescription(commandCode)).arg(parameters.size());
    
    // 创建12字节的命令帧 - 严格遵循下行指令规范的长度要求
    QByteArray frame;
    frame.resize(FRAME_TOTAL_LENGTH);
    
    // 设置帧头 - 根据下行指令规范，前两个字节为固定帧头
    frame[0] = FRAME_HEADER1; // 帧头1 (0x55)
    frame[1] = FRAME_HEADER2; // 帧头2 (0xAA)
    frame[2] = commandCode;   // 命令码 (Byte3)
    frame[3] = FRAME_RESERVED; // 保留位 (Byte4) - 固定为0x00
    
    // 初始化参数区域为0x00
    for (int i = 4; i < FRAME_TOTAL_LENGTH; i++) {
        frame[i] = 0x00;
    }
    
    // 填充参数（如果有），最多8字节
    int paramSize = qMin(parameters.size(), DOWNSTREAM_PARAMETERS_LENGTH);
    for (int i = 0; i < paramSize; i++) {
        frame[4 + i] = parameters[i];
    }
    
    // 输出完整的命令帧内容用于调试
    QString frameHex;
    for (int i = 0; i < frame.size(); i++)
    {
        frameHex += QString("0x%1 ").arg(static_cast<unsigned char>(frame[i]), 2, 16, QChar('0'));
    }
    qDebug() << QString("[CommandFrameBuilder] Built command frame: %1").arg(frameHex.trimmed());
    return frame;
}

/**
 * @brief 构建聚焦模式命令帧
 * 命令码：0x01
 * @return 聚焦模式命令帧
 */
QByteArray CommandFrameBuilder::buildFocusModeFrame()
{
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::FOCUS_MODE_SET));
}

/**
 * @brief 构建扫描模式命令帧
 * 命令码：0x02
 * @param scanMode 扫描模式 (0:单次外触发, 1:单次内触发, 2:重频外触发, 3:重频内触发)
 * @return 扫描模式命令帧
 */
QByteArray CommandFrameBuilder::buildScanModeFrame(uint8_t scanMode)
{
    QByteArray params;
    if(scanMode>3)
    {
        return params;
    }
    params.append(scanMode);
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::SCAN_MODE_SET), params);
}

/**
 * @brief 构建MCP门控设置命令帧
 * 命令码：0x03
 * @param mode 门控模式（1:门控开+外触发, 2:门控开, 3:门控关）
 * @param delayNs 延时时间（纳秒，范围0-2ms）
 * @param pulseWidthNs 脉宽时间（纳秒，范围0-2ms）
 * @return MCP门控设置命令帧
 */
QByteArray CommandFrameBuilder::buildMCPGatingFrame(uint8_t mode, uint32_t delayNs, uint32_t pulseWidthNs)
{
    QByteArray params;
    if(mode==0||mode>3||delayNs>2000000||pulseWidthNs>2000000)
    {
        return params;
    }
    // 设置模式（Byte4）
    params.append(mode);
    
    // 编码延时参数（Byte5-Byte7）
    QByteArray delayBytes = encodeTimeParameter(delayNs);
    params.append(delayBytes);
    
    // 编码脉宽参数（Byte8-Byte10）
    QByteArray pulseWidthBytes = encodeTimeParameter(pulseWidthNs);
    params.append(pulseWidthBytes);
    
    // Byte11固定为0x00
    params.append(static_cast<uint8_t>(0x00));
    
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::MCP_GATING), params);
}

/**
 * @brief 构建阴极门控设置命令帧
 * 命令码：0x04
 * @param mode 门控模式（1:门控开+外触发, 2:门控开, 3:门控关）
 * @param delayNs 延时时间（纳秒，范围0-2ms）
 * @param pulseWidthNs 脉宽时间（纳秒，范围0-2ms）
 * @return 阴极门控设置命令帧
 */
QByteArray CommandFrameBuilder::buildCathodeGatingFrame(uint8_t mode, uint32_t delayNs, uint32_t pulseWidthNs)
{
    QByteArray params;
    
    if(mode==0||mode>3||delayNs>2000000||pulseWidthNs>2000000)
    {
        return params;
    }

    // 设置模式（Byte4）
    params.append(mode);
    
    // 编码延时参数（Byte5-Byte7）
    QByteArray delayBytes = encodeTimeParameter(delayNs);
    params.append(delayBytes);
    
    // 编码脉宽参数（Byte8-Byte10）
    QByteArray pulseWidthBytes = encodeTimeParameter(pulseWidthNs);
    params.append(pulseWidthBytes);
    
    // Byte11固定为0x00
    params.append(static_cast<uint8_t>(0x00));
    
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::CATHODE_GATING), params);
}

/**
 * @brief 构建MCP增益设置命令帧
 * 命令码：0x05
 * @param gain1 增益一的值（范围0-800，单位：V）
 * @param gain2 增益二的值（范围0-800，单位：V）
 * @return MCP增益设置命令帧
 */
QByteArray CommandFrameBuilder::buildMCPGainFrame(uint16_t gain1, uint16_t gain2) {
    QByteArray params;
    // 验证增益范围（0-800V）
    if (gain1 > 800||gain2 > 800)
    {
        return params;
    }

    // 根据文档：
    // Byte4-Byte5: 增益二的值（Byte4对应增益15-8位，Byte5对应增益7-0位）
    // Byte6-Byte7: 增益一的值（Byte6对应增益15-8位，Byte7对应增益7-0位）
    // Byte8-Byte11: 0x00
    
    // 增益二
    params.append(static_cast<uint8_t>((gain2 >> 8) & 0xFF));  // 增益二 15-8位
    params.append(static_cast<uint8_t>(gain2 & 0xFF));         // 增益二 7-0位
    
    // 增益一
    params.append(static_cast<uint8_t>((gain1 >> 8) & 0xFF));  // 增益一 15-8位
    params.append(static_cast<uint8_t>(gain1 & 0xFF));         // 增益一 7-0位
     
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::MCP_GAIN), params);
}

/**
 * @brief 构建档位设置命令帧
 * 命令码：0x06
 * @param gearPosition 档位位置值（bit7对应最高档）
 * @param componentSelection 组件选择（1:快组件, 2:中组件, 3:慢组件）
 * @return 档位设置命令帧
 */
QByteArray CommandFrameBuilder::buildGearSetFrame(uint8_t gearPosition, uint8_t componentSelection)
{
    QByteArray params;
    // 验证组件选择参数（1-3）
    if (componentSelection < 1 || componentSelection > 3)
    {
        return params;
    }
    
    // 根据规范：
    // Byte4: 档位设置值，Bit7对应上位机档位选择下拉框中最上面一档
    // Byte5-Byte10: 0x00
    // Byte11: 组件选择（1:选择快组件，2:选择中组件，3:选择慢组件）
    
    params.append(gearPosition);
    
    // 填充中间字节为0x00
    for (int i = 0; i < 6; i++) {
        params.append(static_cast<uint8_t>(0x00));
    }
    
    params.append(componentSelection);
    
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::GEAR_SET), params);
}

/**
 * @brief 构建快门控制命令帧
 * 命令码：0x08
 * @param open true:打开快门, false:关闭快门
 * @return 快门控制命令帧
 */
QByteArray CommandFrameBuilder::buildShutterControlFrame(bool open)
{
    QByteArray params;
    params.append(open);
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::SHUTTER_CONTROL), params);
}

/**
 * @brief 构建触发源选择命令帧
 * 命令码：0x0B
 * @param source 触发源（0:由扫描触发线触发, 1:由门控触发接口触发）
 * @return 触发源选择命令帧
 */
QByteArray CommandFrameBuilder::buildTriggerSourceFrame(uint8_t source)
{
    QByteArray params;
    if(source>1)
    {
        return params;
    }
    params.append(source);
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::TRIGGER_SOURCE_SET), params);
}

/**
 * @brief 构建TTL状态读回命令帧
 * 命令码：0x09
 * @return TTL状态读回命令帧
 */
QByteArray CommandFrameBuilder::buildTTLStatusReadFrame()
{
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::TTL_STATUS_READ));
}

/**
 * @brief 构建内部触发一次命令帧
 * 命令码：0x0C
 * @return 内部触发一次命令帧
 */
QByteArray CommandFrameBuilder::buildInternalTriggerFrame()
{
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::INTERNAL_TRIGGER_ONCE));
}

/**
 * @brief 构建STPW寄存器配置命令帧
 * @param componentType 组件类型（0:快组件, 1:中组件, 2:慢组件）
 * @param fastValue 最快档配置值
 * @param middleValue 中间档配置值
 * @param slowValue 最慢档配置值
 * @return STPW寄存器配置命令帧
 */
QByteArray CommandFrameBuilder::buildSTPWFrame(uint8_t componentType, QVector<uint16_t> gearPositionValeu)
{
    QByteArray params;
    //判定参数是否正确
    if(componentType>2&&gearPositionValeu.size()!=8)
    {
        return params;
    }
    // 根据下行指令规范，STPW寄存器配置格式具有特定的映射规则：
    // Byte4 (params[0]): 对应STPW[0][0]，最快档位，值乘以8得到MST1脉宽
    // Byte5 (params[1]): 对应STPW[0][1]，次快档位，值乘以8得到MST1脉宽
    // Byte6-Byte10 (params[2-6]): 对应中间档位
    // Byte11 (params[7]): 对应STPW[0][7]，最慢档位，值乘以8得到MST1脉宽
    // 注：这里params索引对应命令帧的Byte5-Byte12位置
    for(int i=0;i<gearPositionValeu.size();i++)
    {
        params.append(gearPositionValeu[i]/8);  // 最快档
    }
    uint8_t commandCode;
    switch (componentType) {
    case 0:  // 快组件
        commandCode = static_cast<uint8_t>(FrameCommandCode::STPW_FAST_COMPONENT);
        break;
    case 1:  // 中组件
        commandCode = static_cast<uint8_t>(FrameCommandCode::STPW_MIDDLE_COMPONENT);
        break;
    case 2:  // 慢组件
        commandCode = static_cast<uint8_t>(FrameCommandCode::STPW_SLOW_COMPONENT);
        break;
    default:
        qWarning() << "Invalid component type for STPW frame, defaulting to fast component";
        commandCode = static_cast<uint8_t>(FrameCommandCode::STPW_FAST_COMPONENT);
    }
    
    return buildCommandFrame(commandCode, params);
}

/**
 * @brief 构建内部触发模式下延时参数设置命令帧
 * 命令码：0x13
 * @param delayNs 延时时间（纳秒，范围0-2ms）
 * @param pulseWidthNs 脉宽时间（纳秒，范围0-2ms）
 * @return 内部触发延时设置命令帧
 */
QByteArray CommandFrameBuilder::buildInternalTriggerDelayFrame(uint32_t delayNs, uint32_t pulseWidthNs)
{
    QByteArray params;
    if(delayNs>2000000||pulseWidthNs>2000000)
    {
        return params;
    }
    // 填充保留字节（Byte4）
    params.append(static_cast<uint8_t>(0x00));
    
    // 编码延时参数（Byte5-Byte7）
    QByteArray delayBytes = encodeTimeParameter(delayNs);
    params.append(delayBytes);
    
    // 编码脉宽参数（Byte8-Byte10）
    QByteArray pulseWidthBytes = encodeTimeParameter(pulseWidthNs);
    params.append(pulseWidthBytes);
    
    // Byte11保留
    params.append(static_cast<uint8_t>(0x00));
    
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::INTERNAL_TRIGGER_DELAY), params);
}

/**
 * @brief 构建外触发信号使能设置命令帧
 * 命令码：0x14
 * @param enabled 使能状态（true:使能外触发, false:切断外触发）
 * @return 外触发使能设置命令帧
 */
QByteArray CommandFrameBuilder::buildExternalTriggerEnableFrame(bool enabled)
{
    QByteArray params;
    params.append(enabled);
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::EXTERNAL_TRIGGER_ENABLE), params);
}

/**
 * @brief 构建串口设备地址查询命令帧
 * 命令码：0x50
 * @return 串口设备查询命令帧
 */
QByteArray CommandFrameBuilder::buildSerialDeviceQueryFrame()
{
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::SERIAL_DEVICE_QUERY));
}

/**
 * @brief 构建监控信号查询命令帧
 * 命令码：0x55
 * @return 监控信号查询命令帧
 */
QByteArray CommandFrameBuilder::buildMonitorSignalQueryFrame()
{
    return buildCommandFrame(static_cast<uint8_t>(FrameCommandCode::MONITOR_SIGNAL_QUERY));
}

/**
 * @brief 解析上行指令帧
 * 验证帧格式并识别命令类型
 * @param frame 接收到的上行指令帧
 * @param commandCode 输出参数，解析出的命令码
 * @return 是否解析成功
 */
bool CommandFrameBuilder::parseUpstreamFrame(const QByteArray& frame, uint8_t& commandCode)
{
    // 验证帧长度和帧头
    if (frame.size() < FRAME_TOTAL_LENGTH ||
        static_cast<uint8_t>(frame[0]) != FRAME_HEADER1 ||
        static_cast<uint8_t>(frame[1]) != FRAME_HEADER2) {
        qWarning() << "Invalid upstream frame format: wrong length or header";
        return false;
    }
    
    // 提取命令码
    commandCode = static_cast<uint8_t>(frame[2]);
    qDebug() << QString("[CommandFrameBuilder] Parsing upstream frame: code=0x%1 (%2)")
                .arg(commandCode, 2, 16, QChar('0'))
                .arg(getCommandDescription(commandCode));
    
    return true;
}

/**
 * @brief 解析AD值数据帧
 * 命令码：0x34
 * @param frame 接收到的AD值帧
 * @param data 输出参数，解析出的AD值数据
 * @return 是否解析成功
 */
bool CommandFrameBuilder::parseADValueFrame(const QByteArray& frame, QVector<uint16_t> &adValues)
{
    // 验证帧长度和命令码
    if (frame.size() < FRAME_TOTAL_LENGTH ||
        static_cast<uint8_t>(frame[2]) != static_cast<uint8_t>(FrameCommandCode::AD_VALUE_SEND)) {
        qWarning() << "Invalid AD value frame format";
        return false;
    }
    
    // 提取Byte3的值，确定上传的是AD0-AD3还是AD4-AD7
    uint8_t dataType = static_cast<uint8_t>(frame[3]);
    
    // 初始化AD值数组

    if (dataType == 0) {
        // 上传AD0-AD3的值
        for (int i = 0; i < 4; i++) {
            // 每个AD值由两个字节组成，低8位在前，高8位在后
            // Byte4-Byte5: ADx低8位和高8位（x=0或4）
            // Byte6-Byte7: ADx低8位和高8位（x=1或5）
            // Byte8-Byte9: ADx低8位和高8位（x=2或6）
            // Byte10-Byte11: ADx低8位和高8位（x=3或7）
            int dataOffset = 4 + (i * 2);
            if (dataOffset + 1 < frame.size()) {
                uint8_t lowByte = static_cast<uint8_t>(frame[dataOffset]);
                uint8_t highByte = static_cast<uint8_t>(frame[dataOffset + 1]);
                adValues[i] = static_cast<uint16_t>(lowByte) | (static_cast<uint16_t>(highByte) << 8);
                qDebug() << QString("AD%1 value: %2 mV").arg(i).arg(adValues[i]);
            }
        }
    } else if (dataType == 1) {
        // 上传AD4-AD7的值
        for (int i = 0; i < 4; i++) {
            int dataOffset = 4 + (i * 2);
            if (dataOffset + 1 < frame.size()) {
                uint8_t lowByte = static_cast<uint8_t>(frame[dataOffset]);
                uint8_t highByte = static_cast<uint8_t>(frame[dataOffset + 1]);
                adValues[i + 4] = static_cast<uint16_t>(lowByte) | (static_cast<uint16_t>(highByte) << 8);
                qDebug() << QString("AD%1 value: %2 mV").arg(i + 4).arg(adValues[i + 4]);
            }
        }
    } else {
        qWarning() << "Invalid AD value data type in frame";
        return false;
    }
    
    return true;
}

/**
 * @brief 解析GPIO状态帧
 * 命令码：0x35
 * @param frame 接收到的GPIO状态帧
 * @param data 输出参数，解析出的GPIO状态数据
 * @return 是否解析成功
 */
bool CommandFrameBuilder::parseGPIOStatusFrame(const QByteArray& frame, QVector<bool>& gpioStatus)
{
    // 验证帧长度和命令码
    if (frame.size() < FRAME_TOTAL_LENGTH ||
        static_cast<uint8_t>(frame[2]) != static_cast<uint8_t>(FrameCommandCode::GPIO_STATUS_SEND)) {
        qWarning() << "Invalid GPIO status frame format";
        return false;
    }

    // 提取Byte3的值，其中bit0-bit7对应GPIO0-GPIO7的状态
    uint8_t gpioBits = static_cast<uint8_t>(frame[3]);
    
    for (int i = 0; i < 8; i++) {
        gpioStatus[i] = (gpioBits & (1 << i)) != 0;
        qDebug() << QString("GPIO%1 status: %2").arg(i).arg(gpioStatus[i] ? "HIGH" : "LOW");
    }
    
    return true;
}

/**
 * @brief 解析TTL输出状态帧
 * 命令码：0x36
 * @param frame 接收到的TTL输出状态帧
 * @param data 输出参数，解析出的TTL状态数据
 * @return 是否解析成功
 */
bool CommandFrameBuilder::parseTTLStatusFrame(const QByteArray& frame, QVector<bool> &ttlStatus)
{
    // 验证帧长度和命令码
    if (frame.size() < FRAME_TOTAL_LENGTH ||
        static_cast<uint8_t>(frame[2]) != static_cast<uint8_t>(FrameCommandCode::TTL_OUTPUT_STATUS_SEND)) {
        qWarning() << "Invalid TTL status frame format";
        return false;
    }
    
    // Byte3: Bit7-Bit4=2'b0000, Bit3-Bit0=TTL19-TTL16
    uint8_t ttlBits1 = static_cast<uint8_t>(frame[3]);
    for (int i = 0; i < 4; i++) {
        if (i < 4) { // TTL16-TTL19
            int ttlIndex = 16 + i;
            if (ttlIndex < 20) {
                ttlStatus[ttlIndex] = (ttlBits1 & (1 << i)) != 0;
                qDebug() << QString("TTL%1 status: %2").arg(ttlIndex).arg(ttlStatus[ttlIndex] ? "HIGH" : "LOW");
            }
        }
    }
    
    // Byte4: Bit7-Bit0=TTL15-TTL8
    uint8_t ttlBits2 = static_cast<uint8_t>(frame[4]);
    for (int i = 0; i < 8; i++) {
        int ttlIndex = 8 + i;
        if (ttlIndex < 20) {
            ttlStatus[ttlIndex] = (ttlBits2 & (1 << i)) != 0;
            qDebug() << QString("TTL%1 status: %2").arg(ttlIndex).arg(ttlStatus[ttlIndex] ? "HIGH" : "LOW");
        }
    }
    
    // Byte5: Bit7-Bit0=TTL7-TTL0
    uint8_t ttlBits3 = static_cast<uint8_t>(frame[5]);
    for (int i = 0; i < 8; i++) {
        int ttlIndex = i;
        if (ttlIndex < 20) {
            ttlStatus[ttlIndex] = (ttlBits3 & (1 << i)) != 0;
            qDebug() << QString("TTL%1 status: %2").arg(ttlIndex).arg(ttlStatus[ttlIndex] ? "HIGH" : "LOW");
        }
    }
    
    return true;
}

/**
 * @brief 解析命令成功解析应答帧
 * 命令码：0x53
 * @param frame 接收到的应答帧
 * @return 是否解析成功
 */
bool CommandFrameBuilder::parseCommandParseSuccessFrame(const QByteArray& frame)
{
    // 验证帧长度和命令码
    if (frame.size() < FRAME_TOTAL_LENGTH ||
        static_cast<uint8_t>(frame[2]) != static_cast<uint8_t>(FrameCommandCode::COMMAND_PARSE_SUCCESS)) {
        qWarning() << "Invalid command parse success frame format (" << (frame.size() < FRAME_TOTAL_LENGTH) << ")";
        return false;
    }
    
    // 命令成功解析应答帧，参数部分应为0x00
    bool success = true;
    for (int i = 3; i < FRAME_TOTAL_LENGTH && i < frame.size(); i++) {
        if (static_cast<uint8_t>(frame[i]) != 0x00) {
            success = false;
            qWarning() << QString("Command parse success frame has non-zero parameter at index %1").arg(i);
            break;
        }
    }
    
    if (success) {
        qDebug() << "Command parsed successfully by device";
    }
    
    return success;
}

/**
 * @brief 辅助方法：将整数转换为字节数组（大端序）
 * @param value 整数值
 * @param byteCount 字节数
 * @return 字节数组（大端序）
 */
QByteArray CommandFrameBuilder::intToBigEndianBytes(uint32_t value, int byteCount) {
    QByteArray bytes;
    for (int i = byteCount - 1; i >= 0; i--)
    {
        bytes.append(static_cast<uint8_t>((value >> (8 * i)) & 0xFF));
    }
    return bytes;
}

/**
 * @brief 辅助方法：将整数转换为字节数组（大端序）
 * @param value 整数值
 * @param byteCount 字节数
 * @return 字节数组（大端序）
 */
QByteArray CommandFrameBuilder::encodeTimeParameter(uint32_t timeNs) {
    // 验证时间范围（0-2ms = 0-2,000,000ns）
    if (timeNs > 2000000) {
        qWarning() << QString("Time parameter %1ns exceeds maximum value of 2,000,000ns (2ms)").arg(timeNs);
        timeNs = 2000000;
    }
    
    // 根据下行指令规范，时间参数使用特殊的3字节编码格式：
    // Byte5: bit7对应延时参数的最高位(bit15)，其余位保留为0
    // Byte6: 中间8位 (bit14-bit7)
    // Byte7: 最低8位 (bit6-bit0)
    // 这种编码方式支持0-2ms范围的精确时间控制
    QByteArray bytes;
    bytes.append(static_cast<uint8_t>((timeNs >> 16) & 0x80));  // 最高位（bit15）放在bit7位置
    bytes.append(static_cast<uint8_t>((timeNs >> 8) & 0xFF));   // 中间8位（bit14-bit7）
    bytes.append(static_cast<uint8_t>(timeNs & 0xFF));          // 最低8位（bit6-bit0）
    
    return bytes;
}

/**
 * @brief 获取命令描述
 * 根据命令码获取对应的中文描述
 * @param commandCode 命令代码
 * @return 命令描述字符串
 */
QString CommandFrameBuilder::getCommandDescription(uint8_t commandCode) {
    switch (commandCode) {
    case static_cast<uint8_t>(FrameCommandCode::FOCUS_MODE_SET): return "聚焦模式";
    case static_cast<uint8_t>(FrameCommandCode::SCAN_MODE_SET): return "扫描模式";
    case static_cast<uint8_t>(FrameCommandCode::MCP_GATING): return "MCP门控设置";
    case static_cast<uint8_t>(FrameCommandCode::CATHODE_GATING): return "阴极门控设置";
    case static_cast<uint8_t>(FrameCommandCode::MCP_GAIN): return "MCP增益设置";
    case static_cast<uint8_t>(FrameCommandCode::GEAR_SET): return "档位设置";
    case static_cast<uint8_t>(FrameCommandCode::TRIG_DELAY_ENABLE): return "触发延时设置（暂不使用）";
    case static_cast<uint8_t>(FrameCommandCode::SHUTTER_CONTROL): return "快门开关控制";
    case static_cast<uint8_t>(FrameCommandCode::TTL_STATUS_READ): return "TTL输出状态读回";
    case static_cast<uint8_t>(FrameCommandCode::TRIGGER_SOURCE_SET): return "触发源选择";
    case static_cast<uint8_t>(FrameCommandCode::INTERNAL_TRIGGER_ONCE): return "内触发一次";
    case static_cast<uint8_t>(FrameCommandCode::STPW_FAST_COMPONENT): return "快组件STPW寄存器配置";
    case static_cast<uint8_t>(FrameCommandCode::STPW_MIDDLE_COMPONENT): return "中组件STPW寄存器配置";
    case static_cast<uint8_t>(FrameCommandCode::STPW_SLOW_COMPONENT): return "慢组件STPW寄存器配置";
    case static_cast<uint8_t>(FrameCommandCode::INTERNAL_TRIGGER_DELAY): return "内触发模式下延时参数设置";
    case static_cast<uint8_t>(FrameCommandCode::EXTERNAL_TRIGGER_ENABLE): return "外触发信号使能设置";
    case static_cast<uint8_t>(FrameCommandCode::SERIAL_DEVICE_QUERY): return "串口设备地址查询";
    case static_cast<uint8_t>(FrameCommandCode::MONITOR_SIGNAL_QUERY): return "监控信号查询";
    // 上行指令描述
    case static_cast<uint8_t>(FrameCommandCode::AD_VALUE_SEND): return "AD值发送";
    case static_cast<uint8_t>(FrameCommandCode::GPIO_STATUS_SEND): return "GPIO状态发送";
    case static_cast<uint8_t>(FrameCommandCode::TTL_OUTPUT_STATUS_SEND): return "TTL输出状态发送";
    case static_cast<uint8_t>(FrameCommandCode::COMMAND_PARSE_SUCCESS): return "命令解析成功响应";
    default:
        return QString("未知命令 (0x%1)").arg(commandCode, 2, 16, QChar('0'));
    }
}
